﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using MovieMetaDataFinder.DataTypes;
using System.Text.RegularExpressions;
using System.Net;

namespace MovieMetaDataFinder
{
    public partial class frmMain : Form
    {

        private string amazonAccessKeyId = "0ZFT7WV4TQ10F3XGA502";
        private string theMovieDBAccessKeyID = "263af9a99271d9bcf824374595e79c8c";
        private string associateTag = "wmediacenterc-20";

        private string lastDirectory = string.Empty;

        public frmMain()
        {
            InitializeComponent();
        }

        private void btnGetDirectory_Click(object sender, EventArgs e)
        {
            string targetDirectory = string.Empty;

            using (FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog())
            {
                folderBrowserDialog.ShowNewFolderButton = true;
                folderBrowserDialog.Description = "Select the folder where your TV shows are located";
                folderBrowserDialog.SelectedPath = this.lastDirectory;
                DialogResult folderBrowserDialogResult = folderBrowserDialog.ShowDialog();

                if (folderBrowserDialogResult != DialogResult.OK)
                {
                    return;
                }

                targetDirectory = folderBrowserDialog.SelectedPath;
                lastDirectory = targetDirectory;
                this.txtGetDirectory.Text = targetDirectory;

                AddToLog("Changed Root Directory To: " + targetDirectory);
            }
        }

        private void AddToLog(string text)
        {
            Program.AppendToLog = DateTime.Now + ":  " + text + "\r\n" + Program.AppendToLog;

            Application.DoEvents();
        }

        private void tmrStatus_Tick(object sender, EventArgs e)
        {
            Program.DateTimeStopTimer = DateTime.Now;
            TimeSpan duration = Program.DateTimeStopTimer - Program.DateTimeStartTimer;
            this.txtTimerStatus.Text =
                duration.Days.ToString("0") + ":" +
                duration.Hours.ToString("00") + ":" +
                duration.Minutes.ToString("00") + ":" +
                duration.Seconds.ToString("00");
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            StartProcess(this.txtGetDirectory.Text);
        }

        private void StartProcess(string targetDirectory)
        {
            List<string> directoryListing = new List<string>();

            AddToLog("Getting a listing of all files *.avi, *.mkv, *.mp4, *.mpg, *.mpeg, *.divx, *.ogm, and *.wmv in " + targetDirectory);
            directoryListing.AddRange(Directory.GetFiles(targetDirectory, "*.avi", SearchOption.AllDirectories).ToList<string>());
            directoryListing.AddRange(Directory.GetFiles(targetDirectory, "*.mkv", SearchOption.AllDirectories).ToList<string>());
            directoryListing.AddRange(Directory.GetFiles(targetDirectory, "*.wmv", SearchOption.AllDirectories).ToList<string>());
            directoryListing.AddRange(Directory.GetFiles(targetDirectory, "*.mp4", SearchOption.AllDirectories).ToList<string>());
            directoryListing.AddRange(Directory.GetFiles(targetDirectory, "*.mpg", SearchOption.AllDirectories).ToList<string>());
            directoryListing.AddRange(Directory.GetFiles(targetDirectory, "*.mpeg", SearchOption.AllDirectories).ToList<string>());
            directoryListing.AddRange(Directory.GetFiles(targetDirectory, "*.divx", SearchOption.AllDirectories).ToList<string>());
            directoryListing.AddRange(Directory.GetFiles(targetDirectory, "*.ogm", SearchOption.AllDirectories).ToList<string>());

            Application.DoEvents();

            List<MoviePathInfo> movies = new List<MoviePathInfo>();
            movies = GetMovies(directoryListing);

            Application.DoEvents();

            try
            {
                this.pnlStatus.Visible = true;
                this.txtTimerStatus.Text = "0:00:00:00";
            }
            catch { }
            Program.DateTimeStartTimer = DateTime.Now;

            try
            {
                this.tmrStatus.Enabled = true;
                this.prgStatus.Maximum = movies.Count;
            }
            catch { }

            foreach (MoviePathInfo movie in movies)
            {
                AddToLog("Movie Found: " + movie.MovieName);

                Title title = GetMetaData(movie);

                if (title != null)
                {
                    if (!string.IsNullOrEmpty(title.BackdropURL))
                    {                        
                        if (!File.Exists(Path.Combine(Path.GetDirectoryName(movie.RootPath), "backdrop.jpg")))
                        {
                            AddToLog("Found Backdrop Image, saving to disk...");
                            SaveImageFromWeb.WriteBytesToFile(Path.Combine(Path.GetDirectoryName(movie.RootPath), "backdrop.jpg"), title.BackdropURL);
                        }
                    }
                }
                else
                {
                    AddToLog("Nothing found for: " + movie.MovieName);
                }

                this.prgStatus.Value++;
            }

            try
            {
                this.tmrStatus.Enabled = false;
                this.txtTimerStatus.Text = "0:00:00:00";
                this.pnlStatus.Visible = false;
                this.prgStatus.Value = 0;
            }
            catch { }
        }

        private Title GetMetaData(MoviePathInfo movie)
        {
            string xmlServiceURL = string.Empty;

            xmlServiceURL = "http://api.themoviedb.org/2.0/Movie.search?title=" + movie.MovieName + "&api_key=" + theMovieDBAccessKeyID;

            Title title = TheMovieDB.TheMovieDB.GetTheMovieDBData(readHtmlPage(xmlServiceURL));

            return title;
        }

        private static string readHtmlPage(string url)
        {
            try
            {
                string result;
                WebResponse objResponse;
                WebRequest objRequest = System.Net.HttpWebRequest.Create(url);
                objResponse = objRequest.GetResponse();

                using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
                {
                    result = sr.ReadToEnd();
                    // Close and clean up the StreamReader 
                    sr.Close();
                }
                return result;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            return null;
        }

        private string DesortTHE(string nameOfTVShow)
        {
            if (nameOfTVShow.Contains(", The"))
            {
                nameOfTVShow = "The " + nameOfTVShow.Replace(", The", "");
            }

            return nameOfTVShow;
        }

        private List<MoviePathInfo> GetMovies(List<string> directoryListing)
        {
            List<MoviePathInfo> response = new List<MoviePathInfo>();

            foreach (string item in directoryListing)
            {
                Application.DoEvents();
                try
                {
                    response.Add(new MoviePathInfo(RemoveMetaDataChars(DesortTHE(GetMovieName(item))), GetSplitPath(item, 1), item));
                }
                catch { }
            }
                       
            try
            {
                response.Sort();
                response.Reverse();
            }
            catch { }

            return response;
        }

        private string RemoveMetaDataChars(string value)
        {
            string response = Regex.Replace(value, @"\(.+\)", String.Empty);
            response = Regex.Replace(response, @"\[.+\]", String.Empty);

            if (!string.IsNullOrEmpty(response))
            {
                // removes anything after the dash
                int dashLocation = response.IndexOf('-');
                response = response.Substring(0, dashLocation - 1).Trim();
            }
            return response;
        }


        public static List<string> removeDuplicates(List<string> inputList)
        {
            Dictionary<string, int> uniqueStore = new Dictionary<string, int>();
            List<string> finalList = new List<string>();

            foreach (string currValue in inputList)
            {
                Application.DoEvents();
                if (!uniqueStore.ContainsKey(currValue))
                {
                    uniqueStore.Add(currValue, 0);
                    finalList.Add(currValue);
                }
            }
            return finalList;
        }

        private string GetMovieName(string file)
        {
            if (SplitString(file, 1).Length > 0)
            {
                return SplitString(file, 1);
            }
            else
            {
                throw new Exception("File naming is invalid for this file: " + file);
            }
        }


        private string SplitString(string file, int item)
        {
            string[] response = file.Split('\\');

            Array.Reverse(response);

            return response[item];
        }

        private string GetSplitPath(string item, int placesBackward)
        {
            string response = string.Empty;

            int totalSectionsInString = item.Split('\\').Count();

            List<string> pathList = new List<string>();

            pathList.AddRange(item.Split('\\'));

            pathList.Reverse();

            bool firstTime = true;
            for (int i = placesBackward - 1; i < totalSectionsInString; i++)
            {
                string slashValue = string.Empty;
                if (firstTime)
                {
                    firstTime = false;
                    slashValue = string.Empty;
                }
                else
                {
                    slashValue = "\\";
                }
                response = pathList[i] + slashValue + response;
            }

            return response;
        }

        private void tmrUpdateUI_Tick(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(Program.AppendToLog))
            {
                string stringToAddToLog = Program.AppendToLog;
                Program.AppendToLog = string.Empty;
                this.txtStatus.Text = stringToAddToLog + this.txtStatus.Text;
            }
        }

        private void frmMain_Load(object sender, EventArgs e)
        {

        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}
